// 1. 导入 RouteRecordRaw ts 类型
import { RouteRecordRaw } from "vue-router"
// 2. 导入 useUserStore
import { useUserStore } from "./user"
// 3. 导入 asyncRoutes 异步路由
import { asyncRoutes } from "@/router"
// 4. 导入 useMenuStore
import { useMenuStore } from "./menu"
// 5. 导入 MenuData ts 类型
import { MenuData } from "@/api/menu"
// 6. 导入 path 第三方包， 本地异步路由路径拼接 和 远程返回路由 对比
import path from "path-browserify"
/**
 * 13-2. 筛选要加载的本地异步路由
 * @param routes 本地异步路由
 * @param  routesPath 远程路由 path 组成的数组
 * @param  basePath 是父路径，递归要用
 * @returns
 */
function generateRoutes(
  routes: RouteRecordRaw[],
  routesPath: string[],
  basePath = "/"
) {
  // 13-2-1. 筛选要加载的本地异步路由  容器
  const routerData: RouteRecordRaw[] = []
  // 13-2-2. 遍历 本地异步路由
  routes.forEach((route) => {
    // 13-2-3. 拼接 本地异步路由 路径，父路径==>path:'/dashboard'   子路径==>path:index，要拼接
    const routePath = path.resolve(basePath, route.path)
    // 13-2-4. 有子节点, 递归筛选
    if (route.children) {
      route.children = generateRoutes(route.children, routesPath, routePath)
    }
    // 13-2-5. 顶级菜单匹配需要将顶级菜放进去，如果子级菜单匹配成功,route.children就会有值, 顶级菜单也要放入
    if (
      routesPath.includes(routePath) ||
      (route.children && route.children.length >= 1)
    ) {
      routerData.push(route)
    }
  })
  // 13-2-6. 返回数据
  return routerData
}
/**
 * 13. 用远程返回扁平化数据, 筛选要加载的本地异步路由
 * @param menus 远程 返回 扁平化数据
 * @param routes 本地异步路由
 * @returns
 */
function filterAsyncRoutes(menus: MenuData[], routes: RouteRecordRaw[]) {
  // 13-1. 获取所有远程路径 path
  const routesPath = menus.map((item) => item.path)
  // 13-2. 筛选要加载的本地异步路由
  return generateRoutes(routes, routesPath)
}

export const usePermissionStore = defineStore("permission", () => {
  // 7. 使用 useUserStore
  const userStore = useUserStore()
  // 8. 使用 useMenuStore
  const menuStore = useMenuStore()

  // 9. 要生成的动态路由
  let accessMenuRoutes: RouteRecordRaw[] = []
  // 10. 路由生成函数， 他的返回值，是给  routes.forEach(router.addRoute) 用的
  const generateRoutes = async () => {
    // 10-1. 获取角色名称数组
    const rolesNames = computed(() =>
      userStore.state.roles.map((item) => item.name)
    )
    // 10-2. 获取角色 id 数组，如果，不是超管理员，是其他角色，，就用 角色 id 数组 生成权限菜单
    const roleIds = computed(() => userStore.state.roles.map((item) => item.id))
    // 10-3. 如果是超级管理员，
    if (rolesNames.value.includes("super_admin")) {
      // 10-3-1. 超级管理员，啥都不用干，返回所有本地异步路由，用于路由注册
      accessMenuRoutes = asyncRoutes
      // 10-3-2. 根据 对应 超级管理员远程菜单 来生成 页面左侧展示的权限菜单
      await menuStore.getAllMenuListByAdmin()
      return accessMenuRoutes
    } else {
      // 11. 如果，不是超管理员，是其他角色, 请求角色 对应的权限路由
      await menuStore.getMenuListByRoles(roleIds.value)
      // 12. 请求角色 对应的权限路由
      const menus = menuStore.state.authMenuList
      // 13. 用远程返回扁平化数据, 筛选要加载的本地异步路由
      accessMenuRoutes = filterAsyncRoutes(menus, asyncRoutes)
      return accessMenuRoutes
    }
  }
  return {
    generateRoutes
  }
})
